import mysql.connector
from mysql.connector import Error
from contextlib import contextmanager
from app.config import Config
from app.utils.logger import logger

class Database:
    """数据库连接管理类"""
    @staticmethod
    def get_connection():
        try:
            conn = mysql.connector.connect(
                host=Config.DATABASE_HOST,
                user=Config.DATABASE_USER,
                password=Config.DATABASE_PASSWORD,
                database=Config.DATABASE_DATABASE,
                autocommit=False  # 禁用自动提交
            )
            return conn
        except Error as e:
            logger.error(f"数据库连接失败: {e}")
            return None

    @contextmanager
    def get_cursor(self, dictionary=True):
        """上下文管理器：自动管理连接和游标"""
        try:
            if not self._conn:
                self._conn = self.get_connection()
            if not self._cursor:
                self._cursor = self._conn.cursor(dictionary=dictionary)
            
            # 重写 cursor.execute 方法来记录 SQL
            original_execute = self._cursor.execute
            def execute_wrapper(query, params=None):
                if params:
                    logger.info(f"执行SQL: {query}, 参数: {params}")
                else:
                    logger.info(f"执行SQL: {query}")
                return original_execute(query, params)
            self._cursor.execute = execute_wrapper
            
            yield self._cursor
            
            # 直接提交，让事务管理由外层控制
            # if self._conn:
            #     self._conn.commit()
                
        except Error as e:
            if self._conn:
                self._conn.rollback()
            logger.error(f"数据库操作失败: {e}")
            raise Exception(f"数据库操作失败: {e}")

    def execute_query(self, query, params=None, dictionary=True):
        """执行查询并返回结果"""
        with self.get_cursor(dictionary=dictionary) as cursor:
            cursor.execute(query, params or ())
            logger.info(f"执行查询: {query}")
            if params:
                logger.info(f"参数: {params}")
            result = cursor.fetchall()
            logger.info(f"查询结果数: {len(result)}")
            return result

    def execute_update(self, query, params=None):
        """执行更新并返回受影响的行数"""
        with self.get_cursor() as cursor:
            cursor.execute(query, params or ())
            logger.info(f"执行更新: {query}")
            if params:
                logger.info(f"参数: {params}")
            affected_rows = cursor.rowcount
            logger.info(f"影响行数: {affected_rows}")
            # 如果不在显式事务中，自动提交
            if not self._in_transaction:
                self._conn.commit()
            return affected_rows

    def __init__(self):
        self._conn = None
        self._cursor = None
        self._in_transaction = False  # 添加事务状态标记

    def begin_transaction(self):
        """开始事务"""
        try:
            if not self._conn:
                self._conn = self.get_connection()
            if self._conn:
                if not self._in_transaction:  # 检查是否已在事务中
                    self._in_transaction = True
                    logger.info("事务开始")
                else:
                    logger.warning("事务已经在进行中，跳过开启操作")
            else:
                raise Exception("无法建立数据库连接")
        except Exception as e:
            logger.error(f"开始事务失败: {str(e)}")
            raise e

    def commit(self):
        """提交事务"""
        try:
            if self._conn and self._in_transaction:
                self._conn.commit()
                self._in_transaction = False
        except Exception as e:
            logger.error(f"提交事务失败: {str(e)}")
            raise e

    def rollback(self):
        """回滚事务"""
        try:
            if self._conn and self._in_transaction:
                self._conn.rollback()
                self._in_transaction = False
        except Exception as e:
            logger.error(f"回滚事务失败: {str(e)}")
            raise e

    def close(self):
        """关闭数据库连接"""
        try:
            if self._cursor:
                self._cursor.close()
            if self._conn:
                if self._in_transaction:
                    self._conn.rollback()  # 如果还在事务中，先回滚
                self._conn.close()
        finally:
            self._cursor = None
            self._conn = None
            self._in_transaction = False